package xin.zhiyin.工具;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/* 文件夹路径："E:/myFolder1/myFolder2/myFolder3"
* 如果父文件夹不存在，会自动创建父文件夹
* */

@Slf4j
public class 文件工具 {
    private static final Logger LOGGER = LoggerFactory.getLogger(文件工具.class);
    public static void 新建文件夹(String 文件夹路径)
    {
        File folders = new File(文件夹路径);
        folders.mkdirs();
    }
    /*
    * 文件名称：含路径的名称
    * */
    public static void 新建文件(String 文件名称,String 文件内容)
    {
        File file = new File(文件名称);
        try{
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(文件内容.getBytes());
            fos.close();
        }catch (IOException e){
            System.out.println("文件创建失败："+e.getMessage());
        }
    }
    public static boolean 删除指定文件(String fileName) {
        File file = new File(fileName);
        if (file.isFile() && file.exists()) {
            file.delete();
            System.out.println("删除文件成功：" + fileName);
            return true;
        } else {
            System.out.println("删除文件失败：" + fileName);
            return false;
        }
    }
    public static void 复制单个文件(String oldPath, String newPath) throws IOException {
        InputStream inStream = null;
        FileOutputStream fs = null;
        try {
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) {// 文件存在时
                inStream = new FileInputStream(oldPath);// 读入原文件
                fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fs != null) {
                    fs.close();
                }
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static  void 清空文件夹(String filePath) {

        Path path = Paths.get(filePath);
        try {
            Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
                    Files.delete(file);
                    LOGGER.info("删除文件: {}", file);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    LOGGER.info("文件夹被删除: {}", dir);
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
    * 删除文件夹需要把包含的文件及文件夹先删除，才能成功
    * 成功返回true,失败返回false
    *
    * */
    public static boolean 删除指定文件夹(String directory) {
        // directory不以文件分隔符（/或\）结尾时，自动添加文件分隔符，不同系统下File.separator方法会自动添加相应的分隔符
        if (!directory.endsWith(File.separator)) {
            directory = directory + File.separator;
        }
        File directoryFile = new File(directory);
        // 判断directory对应的文件是否存在，或者是否是一个文件夹
        if (!directoryFile.exists() || !directoryFile.isDirectory()) {
            System.out.println("文件夹删除失败，文件夹不存在" + directory);
            return false;
        }
        boolean flag = true;
        // 删除文件夹下的所有文件和文件夹
        File[] files = directoryFile.listFiles();
        for (int i = 0; i < files.length; i++) {  // 循环删除所有的子文件及子文件夹
            // 删除子文件
            if (files[i].isFile()) {
                flag = 删除指定文件(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            } else {  // 删除子文件夹
                flag = 删除指定文件夹(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }

        if (!flag) {
            System.out.println("删除失败");
            return false;
        }
        // 最后删除当前文件夹
        if (directoryFile.delete()) {
            System.out.println("删除成功：" + directory);
            return true;
        } else {
            System.out.println("删除失败：" + directory);
            return false;
        }
    }
    public static void 复制整个文件夹内容(String oldPath, String newPath) throws IOException {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            (new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()) {
                    input = new FileInputStream(temp);
                    output = new FileOutputStream(newPath + "/" + (temp.getName()).toString());
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if (temp.isDirectory()) {// 如果是子文件夹
                    复制整个文件夹内容(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (input != null) {
                    input.close();
                }
                if (output != null) {
                    output.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    public static void 移动文件到指定目录(String oldPath, String newPath) throws Exception {
        复制整个文件夹内容(oldPath, newPath);
        删除指定文件夹(oldPath);
    }
    public static List<String> 获取文件夹下所有文件名(String realpath) throws Exception {
        List<String> fileList = new ArrayList<String>();
        try {
            File f = new File(realpath);
            if (!f.exists()) {
                return fileList;
            }

            File[] fa = f.listFiles();
            for (int i = 0; i < fa.length; i++) {
                File fs = fa[i];
                if (fs.isDirectory()) {
                    fileList.add(fs.getName());
                } else {
                    fileList.add(fs.getName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileList;
    }
    public static void 新建多层目录(String folderPath) throws IOException {
        try {
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            if (!myFilePath.exists()) {
                myFilePath.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String 读取txt文件的内容(File file) {
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
            String s = null;
            while ((s = br.readLine()) != null) {// 使用readLine方法，一次读一行
                result.append(System.lineSeparator() + s);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
    public static void 修改文件名称(String  oldFileName,String newFileName){
        File oldFile =  new File(oldFileName);
        File newFile =  new File(newFileName);
        oldFile.renameTo(newFile);
    }
    public static String 获取文件后缀(String fileName) {
        if(fileName!=null && fileName.indexOf(".")>=0) {
            return fileName.substring(fileName.lastIndexOf("."), fileName.length());
        }
        return "";
    }
    public static Boolean 是否为音频文件(String fileName) {
        String [] img_type = new String[]{".mp3", ".ogg"};
        if(fileName==null) {return false;}
        fileName = fileName.toLowerCase();
        for(String type : img_type) {
            if(fileName.endsWith(type)) {return true;}
        }
        return false;
    }

    /**
     * @param file     文件
     * @param fileName 新的随机文件名
     */
    public static String upload(MultipartFile file, String destPath, String fileName) {

        File dest = new File(destPath + fileName);
        //判断文件父目录是否存在
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            //保存文件
            file.transferTo(dest);
        } catch (Exception e) {
            log.info("Save file exception. {}", e.getMessage());
        }
        return destPath + fileName;
    }

    /**
     * 输出文件的后缀名
     * @param fileName
     * @return
     */
    public static String getSuffix(String fileName) {
//        fileName.substring(fileName.lastIndexOf("."))
//        是C#中的字符串操作，它的作用是从文件名字符串中截取最后一个点（.）及其后面的所有字符。这个操作可以用来获取文件的扩展名。
        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 输出文件的新名称 (名字+后缀名)
     * @param fileName
     * @return
     */
    public static String 生成随机文件名称(String fileName) {
        return UUID.randomUUID() + getSuffix(fileName);
    }

    public static String 生成年月日时分秒随机文件名称(String fileName) {
        //获取当前时间戳
        long timestamp = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String formatTimestamp = sdf.format(new Date(timestamp));
        return formatTimestamp + "_" + UUID.randomUUID() + getSuffix(fileName);
    }

    /**
     * @param name
     * @Description 设置响应头部信息
     * @Throws
     * @Return java.lang.String
     * @Date 2023-08-02 13:39:15
     * @Author lgm
     */
    public static String fileContentType(String name) {
        String result = "";
        String fileType = name.toLowerCase();
        if (fileType.endsWith(".png")) {
            result = "image/png";
        } else if (fileType.endsWith(".gif")) {
            result = "image/gif";
        } else if (fileType.endsWith(".jpg") || fileType.endsWith(".jpeg")) {
            result = "image/jpeg";
        } else if (fileType.endsWith(".svg")) {
            result = "image/svg+xml";
        } else if (fileType.endsWith(".ico") || fileType.endsWith(".icon")) {
            result = "image/x-icon";
        }else if (fileType.endsWith(".doc")) {
            result = "application/msword";
        } else if (fileType.endsWith(".xls")) {
            result = "application/x-excel";
        } else if (fileType.endsWith(".zip")) {
            result = "application/zip";
        } else if (fileType.endsWith(".pdf")) {
            result = "application/pdf";
        } else if (fileType.endsWith(".mpeg")) { //MP3
            result = "audio/mpeg";
        } else if (fileType.endsWith(".mp4")) {
            result = "video/mp4";
        } else if (fileType.endsWith(".plain")) {
            result = "text/plain";
        } else if (fileType.endsWith(".html")) {
            result = "text/html";
        } else if (fileType.endsWith(".json")) {
            result = "application/json";
        } else{
            result = "application/octet-stream";
        }
        return result;
    }


}
